package edu.udel.gemini.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
import org.springframework.web.util.UriTemplate;

import edu.udel.gemini.model.Book;
import edu.udel.gemini.model.Instruction;
import edu.udel.gemini.model.Register;
import edu.udel.gemini.repository.BookRepository;
import edu.udel.gemini.repository.ProcessingUnit;

import java.util.ArrayList;
import java.io.IOException;
import java.net.URI;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

@Controller
public class GeminiController {

  @Autowired
  ProcessingUnit cpu;

  @RequestMapping(value="/instructions", method = RequestMethod.GET)
  public @ResponseBody List<Instruction> instructions() {
	  return cpu.getInstructions();
  }

  /* Returns the Instruction corresponding to line number */
  @RequestMapping(value = "/instructions/{id}", method = RequestMethod.GET)
  public @ResponseBody Instruction getInstruction(@PathVariable("id") Integer lineNum) {
	  
	  Instruction instruction = cpu.getInstructionByLine(lineNum);
	  // DO instruction
	  
	  // Increment PC
	  Register pc = null;
	  for (Register r: cpu.getRegisters()) {
		  if (r.getName().equals("PC"))
			  pc = r;
	  }
	  pc.setValue(pc.getValue()+1);
	  
	  if (instruction == null) {
		  throw new BookNotFoundException(lineNum);
	  }
	  
	  return instruction;
  }
  
  /* Returns all registers */
  @RequestMapping(value="/registers", method = RequestMethod.GET)
  public @ResponseBody List<Register> registers() {
    return cpu.getRegisters();
  }
  
  /* Uploads a file */
  @RequestMapping(method = RequestMethod.POST, headers={"content-type=multipart/form-data"})
  public @ResponseBody void uploadAssembly(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
	  DefaultMultipartHttpServletRequest dmhsRequest = (DefaultMultipartHttpServletRequest) request ;
	  MultipartFile multipartFile = (MultipartFile) dmhsRequest.getFile("uploadedFile");

	  cpu.parseFile(multipartFile);
	  
	  // Reset the Program Counter
	  for (Register r: cpu.getRegisters()) {
		  if (r.getName().equals("PC"))
			  r.setValue(1);
	  }
  }

  @ResponseStatus(HttpStatus.NOT_FOUND)
  public class BookNotFoundException extends RuntimeException {
    public BookNotFoundException(Integer id) {
      super("Book '" + id + "' not found.");
    }
  }
}
